from typing import Any, Awaitable, Callable, Dict

from aiogram import BaseMiddleware
from aiogram.types import TelegramObject
from sqlalchemy.ext.asyncio import async_sessionmaker

from poker_bot.database.services import (
    AccountService,
    DepositService,
    DiscountService,
    PaymentMethodService,
    ReviewService,
    UserService,
    WithdrawService,
)
from poker_bot.database.uow.uow import build_uow


class DBSessionMiddleware(BaseMiddleware):
    def __init__(self, sessionmaker: async_sessionmaker) -> None:
        self.sessionmaker = sessionmaker

    async def __call__(
        self,
        handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
        event: TelegramObject,
        data: Dict[str, Any],
    ) -> Any:
        async with self.sessionmaker() as session:
            uow = build_uow(session)
            data["uow"] = uow
            data["user_service"] = UserService(uow)
            data["account_service"] = AccountService(uow)
            data["withdraw_service"] = WithdrawService(uow)
            data["deposit_service"] = DepositService(uow)
            data["payment_method_service"] = PaymentMethodService(uow)
            data["discount_service"] = DiscountService(uow)
            data["review_service"] = ReviewService(uow)

            result = await handler(event, data)
            return result
